package com.react.bluetoothprinter;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Toast;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.example.tscdll.TSCActivity;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Set;
import java.util.Vector;

import static com.facebook.common.internal.ByteStreams.copy;
import static com.react.bluetoothprinter.RNBluetoothPackage.TAG;

public class RNBluetoothModule extends ReactContextBaseJavaModule {

    private BluetoothAdapter mBtAdapter;
    private ArrayList<String> mPairedDevicesArrayAdapter = new ArrayList<String>();
    private ArrayList<String> mNewDevicesArrayAdapter = new ArrayList<String>();
    private ReactContext mReactContext;
    private TSCActivity printUtils;
    private ConnectPrinter cPrinter;

    public RNBluetoothModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mReactContext = reactContext;
        final Runnable runnable = new Runnable() {
            @Override
            public void run() {
                printUtils = new TSCActivity();
                cPrinter = new ConnectPrinter();
            }
        };
        new Thread() {
            public void run() {
                new Handler(Looper.getMainLooper()).post(runnable);//在子线程中直接去new 一个handler
                //这种情况下，Runnable对象是运行在主线程中的，不可以进行联网操作，但是可以更新UI
            }
        }.start();
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        mReactContext.registerReceiver(mReceiver, filter);

        // Register for broadcasts when discovery has finished
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        mReactContext.registerReceiver(mReceiver, filter);
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    @Override
    public String getName() {
        return "RNBluetoothModule";
    }


    @ReactMethod
    public void scanForPeripherals() {


        Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();

        // If there are paired devices, add each one to the ArrayAdapter
        if (pairedDevices.size() > 0) {
            for (BluetoothDevice device : pairedDevices) {
                Log.i(TAG, device.getName());
                mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                WritableMap map = new WritableNativeMap();
                map.putString("name", device.getName());
                map.putString("mac", device.getAddress());
                map.putString("paired", "1");
                mReactContext
                        .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                        .emit("BluetoothEvent", map);
            }
        } else {
            String noDevices = "无配对";
            mPairedDevicesArrayAdapter.add(noDevices);
        }

        if (mBtAdapter.isDiscovering()) {
            mBtAdapter.cancelDiscovery();
        }
        mBtAdapter.startDiscovery();

    }

    @ReactMethod
    public void labelPrint(ReadableMap data) {

        String logisticsName = data.getString("logisticsName");
        String userName = data.getString("userName");
        String mobile = data.getString("mobile");
        String address = data.getString("address");
        String collection = data.getString("collection");
        final String currentCount = data.getString("currentCount");
//        final String totalCount = data.getString("totalCount");
        String number = data.getString("number");
        String account = data.getString("account");
        String storeMobile = data.getString("storeMobile");
        final String qrImage = data.getString("qrImage");
        new Thread() {
            @Override
            public void run() {

                printUtils.clearbuffer();

                String m = "TEXT 260,50,\"TSS24.BF2\",0,1,1,\"RN蓝牙打印机\n";
                byte str[] = new byte[0];
                try {
                    str = m.getBytes("GBK");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                printUtils.sendcommand(str);
                String str1 = "QRCODE 260,120,L,6,A,0,M1,S3,\"www.baidu.com\n";
                printUtils.sendcommand(str1);
                printUtils.printlabel(1, 1);

            }
        }.start();
    }


    @ReactMethod
    public void connect(final String macName) {

        if (macName == null) {
            //ConnectEvent
            EventMethod("0", "Mac地址为空", "ConnectEvent");
        }

        final Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    printUtils.openport(macName);
                    EventMethod("1", "连接成功", "ConnectEvent");
                } catch (Exception e) {
                    EventMethod("0", "连接异常", "ConnectEvent");
                }

                StringBuffer sb = new StringBuffer();
                sb.append(printUtils.status());
                String newStr = sb.toString();
                if (newStr.equals("[0]"))

                {
                    Toast("就绪");
                    WritableMap map = new WritableNativeMap();
                    map.putString("code", "0");
                    map.putString("error", "连接");
                    mReactContext
                            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                            .emit("ConnectEvent", map);

                } else if (newStr.equals("[4]"))

                {
                    Toast("缺纸");
                } else if (newStr.equals("[2]"))

                {
                    Toast("标签检测错误");
                } else if (newStr.equals("[8]"))

                {
                    Toast("无碳带");
                } else if (newStr.equals("[16]"))

                {
                    Toast("暂停");
                } else if (newStr.equals("[32]"))

                {
                    Toast("打印中");
                } else if (newStr.equals("[65]"))

                {
                    Toast("开盖有纸");
                } else if (newStr.equals("[69]"))

                {
                    Toast("开盖缺纸");
                } else if (newStr.equals("[128]"))

                {
                    Toast("太热了");
                }
            }
        };
        new Thread() {
            public void run() {
                new Handler(Looper.getMainLooper()).post(runnable);//在子线程中直接去new 一个handler
                //这种情况下，Runnable对象是运行在主线程中的，不可以进行联网操作，但是可以更新UI
            }
        }.start();
    }

    /**
     * 注册监听事件
     *
     * @param code
     * @param msg
     * @param event
     */
    private void EventMethod(String code, String msg, String event) {
        WritableMap map = new WritableNativeMap();
        map.putString("code", code);
        map.putString("error", msg);
        mReactContext
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(event, map);
        Toast(msg);
    }

    public void Toast(String str) {
        Toast.makeText(getReactApplicationContext(), str, Toast.LENGTH_LONG).show();
    }


    @ReactMethod
    public void printerStatus(final String macName) {
        try {
            cPrinter.ConnectThreadAddress(macName);
        } catch (Exception e) {
            EventMethod("0", "连接异常", "ConnectEvent");
        }
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(cPrinter.status());
        String status = stringBuffer.toString();
        if (status.equals("[0]")) {
            EventMethod("1", "连接成功", "ConnectEvent");

        } else if (status.equals("[4]"))

        {
            Toast("缺纸");
        } else if (status.equals("[2]"))

        {
            Toast("标签检测错误");
        } else if (status.equals("[8]"))

        {
            Toast("无碳带");
        } else if (status.equals("[16]"))

        {
            Toast("暂停");
        } else if (status.equals("[32]"))

        {
            Toast("打印中");
        } else if (status.equals("[65]"))

        {
            Toast("开盖有纸");
        } else if (status.equals("[69]"))

        {
            Toast("开盖缺纸");
        } else if (status.equals("[128]"))

        {
            Toast("太热了");
        }
    }

    @ReactMethod
    public void close() {
        printUtils.closeport();
    }

    @ReactMethod
    public void openBluetooth() {
        mBtAdapter.enable();
    }

    @ReactMethod
    public void closeBluetooth() {
        mBtAdapter.disable();
    }


    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Get the BluetoothDevice object from the Intent
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // If it's already paired, skip it, because it's been listed already
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                    WritableMap map = new WritableNativeMap();
                    map.putString("name", device.getName());
                    map.putString("mac", device.getAddress());
                    mReactContext
                            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                            .emit("BluetoothEvent", map);
                }
                // When discovery is finished, change the Activity title
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                // setProgressBarIndeterminateVisibility(false);
                if (mNewDevicesArrayAdapter.size() == 0) {
                    String noDevices = "无蓝牙";
                    mNewDevicesArrayAdapter.add(noDevices);
                }
            }
        }
    };

    /**
     * 得到本地或者网络上的bitmap url - 网络或者本地图片的绝对路径,比如:
     * <p>
     * A.网络路径: url="http://blog.foreverlove.us/girl2.png" ;
     * <p>
     * B.本地路径:url="file://mnt/sdcard/photo/image.png";
     * <p>
     * C.支持的图片格式 ,png, jpg,bmp,gif等等
     *
     * @param url
     * @return
     */
    public static Bitmap GetLocalOrNetBitmap(String url) {
        Bitmap bitmap = null;
        InputStream in = null;
        BufferedOutputStream out = null;
        try {
            in = new BufferedInputStream(new URL(url).openStream(), 2 * 1024);
            final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
            out = new BufferedOutputStream(dataStream, 2 * 1024);
            copy(in, out);
            out.flush();
            byte[] data = dataStream.toByteArray();
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            data = null;
            return bitmap;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

